<template>
  <div
    :class="className"
    :style="{height: height, width: width}"
  />
</template>

<script lang="ts">
import * as echarts from 'echarts'
import { EChartsOption } from 'echarts'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { mixins } from 'vue-class-component'
import ResizeMixin from '@/components/Charts/mixins/resize'
import { PercentItem } from '@/api-scp/types'

@Component({
  name: 'PercentagesChart',
  components: {}
})
export default class extends mixins(ResizeMixin) {
  @Prop({ default: 'chart' }) private className!: string
  @Prop({ default: '100%' }) private width!: string
  @Prop({ default: '200px' }) private height!: string
  @Prop({ default: 7 }) private spacingPercent!: number
  @Prop({ default: -7 }) private centerYOffsetPercent!: number
  @Prop() private title?: string
  @Prop({
    required: true,
    default: []
  }) private percents!: PercentItem[]

  @Watch('percents', { deep: true })
  private onPercentsChange(value: PercentItem[]) {
    this.setOptions(value)
  }

  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
  }

  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  }

  private async initChart() {
    this.chart = echarts.init(this.$el as HTMLDivElement)

    this.setOptions(this.percents)
  }

  private setOptions(percents: PercentItem[]) {
    if (!this.chart) {
      return
    }

    const title = { text: this.title ? this.title : undefined }

    const spacingPercent = this.spacingPercent
    const centerYOffsetPercent = this.centerYOffsetPercent

    const count = percents.length
    // PH: PercentHorizon
    const diameterPH = (100 - spacingPercent * (count + 1)) / count
    const chartWidth = this.chart.getWidth()
    const chartHeight = this.chart.getHeight()
    // PV: PercentVertical
    const diameterPV = chartWidth * diameterPH / chartHeight
    const pieRadius = chartWidth * diameterPH / 200
    const centerY = chartHeight * (50 + centerYOffsetPercent) / 100
    const option: EChartsOption =
      {
        title,
        series: percents.map((pi, i) => {
          const xPercent = (spacingPercent * (i + 1) + diameterPH * i + diameterPH / 2)
          const centerX = chartWidth * xPercent / 100
          return {
            type: 'pie',
            name: pi.name,
            center: [xPercent + '%', (50 + centerYOffsetPercent) + '%'],
            radius: diameterPV + '%',
            label: { show: false },
            labelLayout: function(params) {
              return {
                x: centerX,
                y: centerY + pieRadius + 10,
                verticalAlign: 'top',
                align: 'center',
                width: pieRadius * 2 + chartWidth * spacingPercent / 100
              }
            },
            data: [{
              name: pi.name,
              value: pi.percent,
              label: {
                show: true,
                formatter: pi.nameWithLineBreak || pi.name + '\n{d}%',
                fontWeight: 'bold',
                lineHeight: 20,
                height: 80
              }
            }, {
              name: '-',
              value: 100 - pi.percent,
              label: { show: false },
              itemStyle: {
                opacity: 0.08
              }
            }]
          }
        })
      }

    console.log(JSON.stringify(option, null, 2))

    this.chart.setOption(option)
  }
}
</script>

<style lang="scss" scoped>

</style>
